"""创建测试数据的Django管理命令

用于生成LinkBook项目的测试数据，包括用户、分类、标签、笔记和分享等。
"""

import random
from datetime import datetime, timedelta
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.utils import timezone
from faker import Faker

from apps.notes.models import Category, Tag, Note, Attachment
from apps.sharing.models import SharedNote, ShareComment

User = get_user_model()
fake = Faker('zh_CN')


class Command(BaseCommand):
    """创建测试数据命令类"""
    
    help = '创建LinkBook项目的测试数据'
    
    def add_arguments(self, parser):
        """添加命令行参数"""
        parser.add_argument(
            '--users',
            type=int,
            default=10,
            help='创建用户数量（默认10个）'
        )
        parser.add_argument(
            '--categories',
            type=int,
            default=8,
            help='创建分类数量（默认8个）'
        )
        parser.add_argument(
            '--tags',
            type=int,
            default=20,
            help='创建标签数量（默认20个）'
        )
        parser.add_argument(
            '--notes',
            type=int,
            default=50,
            help='创建笔记数量（默认50个）'
        )
        parser.add_argument(
            '--shares',
            type=int,
            default=15,
            help='创建分享数量（默认15个）'
        )
    
    def handle(self, *args, **options):
        """执行命令主逻辑"""
        self.stdout.write(self.style.SUCCESS('开始创建测试数据...'))
        
        # 创建测试用户
        users = self.create_users(options['users'])
        self.stdout.write(self.style.SUCCESS(f'创建了 {len(users)} 个用户'))
        
        # 创建分类
        categories = self.create_categories(users, options['categories'])
        self.stdout.write(self.style.SUCCESS(f'创建了 {len(categories)} 个分类'))
        
        # 创建标签
        tags = self.create_tags(users, options['tags'])
        self.stdout.write(self.style.SUCCESS(f'创建了 {len(tags)} 个标签'))
        
        # 创建笔记
        notes = self.create_notes(users, categories, tags, options['notes'])
        self.stdout.write(self.style.SUCCESS(f'创建了 {len(notes)} 个笔记'))
        
        # 创建分享
        shares = self.create_shares(notes, options['shares'])
        self.stdout.write(self.style.SUCCESS(f'创建了 {len(shares)} 个分享'))
        
        # 创建分享评论
        comments = self.create_share_comments(users, shares)
        self.stdout.write(self.style.SUCCESS(f'创建了 {len(comments)} 个分享评论'))
        
        self.stdout.write(self.style.SUCCESS('测试数据创建完成！'))
        self.stdout.write(self.style.WARNING('管理员账户: admin / admin123456'))
        self.stdout.write(self.style.WARNING('测试用户账户: user1 / password123 (以此类推)'))
    
    def create_users(self, count):
        """创建测试用户"""
        users = []
        
        # 首先获取已存在的admin用户
        try:
            admin_user = User.objects.get(username='admin')
            users.append(admin_user)
        except User.DoesNotExist:
            pass
        
        for i in range(1, count + 1):
            username = f'user{i}'
            email = f'user{i}@linkbook.com'
            
            # 检查用户是否已存在
            if not User.objects.filter(username=username).exists():
                user = User.objects.create_user(
                    username=username,
                    email=email,
                    password='password123',
                    first_name=fake.first_name(),
                    last_name=fake.last_name()
                )
                users.append(user)
            else:
                # 如果已存在，获取现有用户
                user = User.objects.get(username=username)
                users.append(user)
        
        return users
    
    def create_categories(self, users, count):
        """创建测试分类"""
        categories = []
        category_names = [
            '技术笔记', '学习心得', '工作总结', '生活随笔',
            '读书笔记', '项目文档', '会议记录', '灵感收集'
        ]
        colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F']
        
        for i in range(min(count, len(category_names))):
            name = category_names[i]
            slug = f'category-{i+1}'  # 使用数字确保唯一性
            
            # 检查分类是否已存在（按slug检查）
            if not Category.objects.filter(slug=slug).exists():
                category = Category.objects.create(
                    name=name,
                    slug=slug,
                    description=fake.text(max_nb_chars=100),
                    color=colors[i % len(colors)],
                    created_by=random.choice(users),
                    order=i + 1
                )
                categories.append(category)
            else:
                # 如果已存在，获取现有分类
                category = Category.objects.get(slug=slug)
                categories.append(category)
        
        return categories
    
    def create_tags(self, users, count):
        """创建测试标签"""
        tags = []
        tag_names = [
            'Python', 'Django', 'JavaScript', 'React', 'Vue.js', 'Node.js',
            '数据库', '算法', '设计模式', '架构', '前端', '后端',
            '机器学习', '人工智能', '区块链', '云计算', '微服务', '容器化',
            '测试', '部署'
        ]
        colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
        
        for i in range(min(count, len(tag_names))):
            name = tag_names[i]
            slug = f'tag-{i+1}'  # 使用数字确保唯一性
            
            # 检查标签是否已存在（按slug检查）
            if not Tag.objects.filter(slug=slug).exists():
                tag = Tag.objects.create(
                    name=name,
                    slug=slug,
                    color=random.choice(colors),
                    created_by=random.choice(users),
                    usage_count=random.randint(1, 20)
                )
                tags.append(tag)
            else:
                # 如果已存在，获取现有标签
                tag = Tag.objects.get(slug=slug)
                tags.append(tag)
        
        return tags
    
    def create_notes(self, users, categories, tags, count):
        """创建测试笔记"""
        notes = []
        statuses = ['draft', 'published', 'archived']
        
        for i in range(count):
            # 生成笔记内容
            title = fake.sentence(nb_words=6).rstrip('.')
            content = self.generate_note_content()
            
            # 创建笔记
            note = Note.objects.create(
                title=title,
                content=content,
                status=random.choice(statuses),
                author=random.choice(users),
                category=random.choice(categories) if categories else None,
                view_count=random.randint(0, 100),
                is_pinned=random.choice([True, False]) if random.random() < 0.1 else False,
                is_favorite=random.choice([True, False]) if random.random() < 0.2 else False,
                created_at=timezone.now() - timedelta(days=random.randint(1, 365))
            )
            
            # 添加标签
            if tags:
                note_tags = random.sample(tags, k=random.randint(1, min(5, len(tags))))
                note.tags.set(note_tags)
            
            notes.append(note)
        
        return notes
    
    def generate_note_content(self):
        """生成笔记内容"""
        content_templates = [
            # 技术笔记模板
            """# {title}

## 概述
{overview}

## 主要内容
{main_content}

## 代码示例
```python
{code_example}
```

## 总结
{summary}

## 参考资料
- {reference1}
- {reference2}""",
            
            # 学习笔记模板
            """# {title}

## 学习目标
{learning_goals}

## 重点内容
{key_points}

## 难点分析
{difficult_points}

## 实践练习
{practice}

## 心得体会
{reflection}""",
            
            # 工作总结模板
            """# {title}

## 工作内容
{work_content}

## 完成情况
{completion_status}

## 遇到的问题
{problems}

## 解决方案
{solutions}

## 经验教训
{lessons_learned}

## 下一步计划
{next_steps}"""
        ]
        
        template = random.choice(content_templates)
        
        return template.format(
            title=fake.sentence(nb_words=4).rstrip('.'),
            overview=fake.text(max_nb_chars=200),
            main_content=fake.text(max_nb_chars=300),
            code_example='def hello_world():\n    print("Hello, World!")\n    return True',
            summary=fake.text(max_nb_chars=150),
            reference1=fake.url(),
            reference2=fake.url(),
            learning_goals=fake.text(max_nb_chars=100),
            key_points=fake.text(max_nb_chars=250),
            difficult_points=fake.text(max_nb_chars=200),
            practice=fake.text(max_nb_chars=180),
            reflection=fake.text(max_nb_chars=150),
            work_content=fake.text(max_nb_chars=300),
            completion_status=fake.text(max_nb_chars=100),
            problems=fake.text(max_nb_chars=200),
            solutions=fake.text(max_nb_chars=250),
            lessons_learned=fake.text(max_nb_chars=180),
            next_steps=fake.text(max_nb_chars=120)
        )
    
    def create_shares(self, notes, count):
        """创建测试分享"""
        shares = []
        
        # 只分享已发布的笔记
        published_notes = [note for note in notes if note.status == 'published']
        
        if not published_notes:
            return shares
        
        for i in range(min(count, len(published_notes))):
            note = random.choice(published_notes)
            
            # 避免重复分享同一篇笔记
            if SharedNote.objects.filter(note=note).exists():
                continue
            
            share = SharedNote.objects.create(
                note=note,
                shared_by=note.author,
                title=note.title,
                description=fake.text(max_nb_chars=200),
                permission=random.choice(['view', 'comment']),
                scope=random.choice(['public', 'link']),
                password=fake.password(length=8) if random.random() < 0.2 else '',
                expires_at=timezone.now() + timedelta(days=random.randint(30, 365)) if random.random() < 0.3 else None,
                view_count=random.randint(0, 50),
                unique_visitors=random.randint(0, 30)
            )
            shares.append(share)
        
        return shares
    
    def create_share_comments(self, users, shares):
        """创建分享评论"""
        comments = []
        
        # 只为允许评论的分享创建评论
        commentable_shares = [share for share in shares if share.allow_comments]
        
        for share in commentable_shares:
            # 每个分享随机创建1-5个评论
            comment_count = random.randint(1, 5)
            
            for i in range(comment_count):
                comment = ShareComment.objects.create(
                    shared_note=share,
                    author_name=fake.name(),
                    author_email=fake.email(),
                    content=fake.text(max_nb_chars=200),
                    likes_count=random.randint(0, 10),
                    created_at=timezone.now() - timedelta(days=random.randint(1, 20))
                )
                comments.append(comment)
        
        return comments